package com.mindata.blockchain.socket.server;

import com.mindata.blockchain.ApplicationContextProvider;
import com.mindata.blockchain.common.ResultPack;
import com.mindata.blockchain.core.manager.PermissionManager;
import com.mindata.blockchain.socket.base.AbstractAioHandler;
import com.mindata.blockchain.socket.distruptor.base.BaseEvent;
import com.mindata.blockchain.socket.distruptor.base.MessageProducer;
import com.mindata.blockchain.socket.packet.BlockPacket;
import com.mindata.blockchain.socket.packet.PacketType;
import lombok.extern.slf4j.Slf4j;
import org.tio.core.ChannelContext;
import org.tio.core.Node;
import org.tio.core.intf.Packet;
import org.tio.server.intf.ServerAioHandler;

/**
 * server端处理所有client请求的入口
 *
 * @author wuweifeng wrote on 2018/3/12.ClientStarter
 */
@Slf4j(topic = "BlockServerAioHandler")
public class BlockServerAioHandler extends AbstractAioHandler implements ServerAioHandler {

    /**
     * 自己是server，此处接收到客户端来的消息。这里是入口
     */
    @Override
    public void handler(Packet packet, ChannelContext channelContext) {
        BlockPacket blockPacket = (BlockPacket) packet;
        PacketType type = PacketType.fromValue(blockPacket.getType());
        log.info("<<<<<<<<<<<<<<<<<服务端接收消息 type:{} packet:{}", type.getValue(), blockPacket);

        //校验权限
        Node node = channelContext.getClientNode();
        ResultPack resultPack = ApplicationContextProvider.getBean(PermissionManager.class).checkNodeAuth(node);
        if (resultPack.isFailed()) {
            log.warn("节点:{} 不是合法联盟,忽略消息处理", node);
            return;
        }

        //使用Disruptor来publish消息。所有收到的消息都进入Disruptor，同BlockClientAioHandler
        ApplicationContextProvider.getBean(MessageProducer.class).publish(new BaseEvent(blockPacket, channelContext));
    }
}
